package dao;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import dto.FolderDTO;

import model.Folder;
import model.Resource;

/**
 * @author soreas Session Bean implementation class FolderDao
 */
@Stateless
public class FolderDao {

	@PersistenceContext
	EntityManager em;

	/**
	 * Default constructor.
	 */
	public FolderDao() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * @author soreas
	 * @param pId
	 *            idul dupa care se cauta in baza de date obiectul Folder
	 * @return obiectul de tip Folder
	 */
	public Folder getFolderByID(int pId) {
		Folder f = new Folder();
		try {
			f = em.find(Folder.class, pId);

		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return f;
	}

	/**
	 * @author tokea
	 * @param repId
	 * @return List<Folder>
	 */
	public List<Folder> getFolderListFromRepository(int repId) {
		List<Folder> flist = new ArrayList<Folder>();
		try {
			String query = "SELECT f FROM Folder f ";
			List<Folder> subList = em.createQuery(query, Folder.class).getResultList();
			for (Folder f : subList)
				if (f.getRepository().getId() == repId && !(f instanceof model.Resource))
					flist.add(f);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return flist;
	}

	/**
	 * @author soreas
	 * 
	 * @param pUsername
	 *            String ce reprezinta numele userului pentru care cautam
	 *            foldere
	 * @return Lista de foldere
	 */
	public List<Folder> getFoldersForAUser(String pUsername) {
		return em
				.createQuery(
						"select f from Membership m , Folder f, User u "
								+ " where m.folder.id = f.id and u.id = m.user.id and f.id = f.folder.id and u.name = ?1 ", Folder.class)
				.setParameter(1, pUsername).getResultList();

	}

	/**
	 * @author Zsombor
	 * @param FolderDTO
	 *            Creates a folder
	 */
	public void addFolder(FolderDTO fDto) {
		Folder newFolder = new Folder();
		int idParent = fDto.getId_parent();
		newFolder.setFolder(em.find(Folder.class, idParent));
		newFolder.setName(fDto.getName());
		int version = getNewVersion(idParent);
		newFolder.setVersion(version);
		em.persist(newFolder);
		em.flush();
		em.refresh(newFolder);
		fDto.setVersion(version);
		fDto.setId(newFolder.getId());
		setParentFoldersVersion(version, idParent);
	}

	/**
	 * @author Zsombor
	 * @param FolderDTO
	 *            Deletes a folder
	 */
	public void deleteFolder(int id) {
		Folder f = em.find(Folder.class, id);

		if (f.getClass() == Folder.class) {
			em.remove(f);
		}

	}

	/**
	 * @author tokea
	 * @param idParentFolder
	 * @return new version
	 */
	public int getNewVersion(int idParentFolder) {
		int version = 1;
		Folder parent = em.find(Folder.class, idParentFolder);
		Folder repository = null;
		repository = parent.getRepository();
		if (repository != null) {
			version = repository.getVersion() + 1;
		}
		return version;
	}

	/**
	 * @author tokea
	 * @param version
	 * @param idParent
	 */
	public void setParentFoldersVersion(int version, int idParent) {
		Folder parentF = em.find(Folder.class, idParent);
		if (parentF != parentF.getFolder()) {
			parentF.getFolder().setVersion(version);
			setParentFoldersVersion(version, parentF.getFolder().getId());
		}
	}

	/**
	 * @author tokea
	 * @param parentId
	 * @param name
	 * @return boolean unique
	 */
	public boolean verifyNameUniqueInFolder(int parentId, String name) {
		boolean unique = true;
		String query = "SELECT f FROM Folder f WHERE f.folder.id = :parentId AND f.name = :name";
		List<Folder> flist = em.createQuery(query, Folder.class).setParameter("parentId", parentId).setParameter("name", name).getResultList();
		if (flist.size() > 0 && !(flist.get(0) instanceof Resource))
			unique = false;
		return unique;
	}
}
